﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using RestSharp;
using RestSharp.Authenticators.OAuth;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;

namespace WeiTalk.OAuth.Sina
{
    public class OAuth:OAuthBase
    {
        public string Password { get; protected set; }
        public string UserName { get; protected set; }
        public string AppKey { get; private set; }
        public string CallbackUrl { get; set; }

        public AccessToken AccessToken{get; protected set;}
        public bool IsOK { get; protected set; }

        CookieContainer MyCookieContainer = new CookieContainer();

        public OAuth(string userName, string password, string appKey, string callbackUrl)
        {
            Password = password;
            UserName = userName;
            AppKey = appKey;
            CallbackUrl = callbackUrl;
            IsOK = false;
        }

        public OAuth(string userName, string passWord, string appKey)
            : this(userName, passWord, appKey, null)
        { }

        public override void Authenticate(HandleResult handle, HandleExceptionResult exceptionHandler)
        {
            CookieContainer MyCookieContainer = new CookieContainer();
            HttpWebRequest http = WebRequest.Create(AUTHORIZE_URL + string.Format("?action=submit&withOfficalFlag=0&ticket=&isLoginSina=&response_type=token&regCallback=&redirect_uri={0}&client_id={1}&state=&from=&userId={2}&passwd={3}&display=js", Uri.EscapeDataString(string.IsNullOrEmpty(CallbackUrl) ? "" : CallbackUrl), Uri.EscapeDataString(AppKey), Uri.EscapeDataString(UserName), Uri.EscapeDataString(Password))) as HttpWebRequest;
            http.Headers["Referer"] = GetAuthorizeURL();
            http.Method = "POST";
            http.ContentType = "application/x-www-form-urlencoded";

          var result =  http.BeginGetResponse((ar) =>
            {
                try
                {
                    HttpWebRequest theResponse = ((HttpWebRequest)ar.AsyncState);
                    WebResponse webResponse = theResponse.EndGetResponse(ar);
                    using (StreamReader reader = new StreamReader(webResponse.GetResponseStream()))
                    {
                        try
                        {
                            var html = reader.ReadToEnd();
                            var pattern1 = @"\{""access_token"":""(?<token>.{0,32})"",""remind_in"":""(?<remind>\d+)"",""expires_in"":(?<expires>\d+),""uid"":""(?<uid>\d+)""\}";
                            var pattern2 = @"\{""access_token"":""(?<token>.{0,32})"",""remind_in"":""(?<remind>\d+)"",""expires_in"":(?<expires>\d+),""refresh_token"":""(?<refreshtoken>.{0,32})"",""uid"":""(?<uid>\d+)""\}";
                            if (!string.IsNullOrEmpty(html) && (Regex.IsMatch(html, pattern1) || Regex.IsMatch(html, pattern2)))
                            {
                                var group = Regex.IsMatch(html, "refresh_token") ? Regex.Match(html, pattern2) : Regex.Match(html, pattern1);

                                AccessToken = new Sina.AccessToken
                                {
                                    Token = group.Groups["token"].Value,
                                    ExpiresIn = Convert.ToInt32(group.Groups["expires"].Value),
                                    UID = group.Groups["uid"].Value
                                };
                            }
                        }
                        finally
                        {
                            reader.Close();
                            if (AccessToken == null)
                            {
                                exceptionHandler("授权错误,请检察用户名或密码。");
                                //throw new OAuthException("授权错误");
                            }
                            else
                            {
                                handle(AccessToken);
                            }
                        }
                    }
                }
                catch (WebException)
                {
                    exceptionHandler("请检网络是否已连接。");
                }
            }, http);
        }

        private static void TimeoutCallback(object state, bool timedOut)
        {
            if (timedOut)
            {
                HttpWebRequest request = state as HttpWebRequest;
                if (request != null)
                {
                    request.Abort();
                }
            }
        }

        public string GetAuthorizeURL()
        {
            Dictionary<string, string> config = new Dictionary<string, string>()
			{
				{"client_id",AppKey},
				{"redirect_uri",CallbackUrl},
				{"response_type", ResponseType.Code.ToString().ToLower()},
				{"state",string.Empty},
				{"display",DisplayType.Default.ToString().ToLower()},
			};
            UriBuilder builder = new UriBuilder(AUTHORIZE_URL);
            builder.Query = Utility.BuildQueryString(config);

            return builder.ToString();
        }

        public override string AUTHORIZE_URL
        {
            get { return "https://api.weibo.com/oauth2/authorize"; }
        }

        public override string ACCESS_TOKEN_URL
        {
            get { return "https://api.weibo.com/oauth2/access_token"; }
        }
    }
}
